﻿
using AdventureWorks.DataAccess.repository;
using AdventureWorks.Domain;
using NUnit.Framework;
using NHibernate.Linq;
using System.Linq;
using AdventureWorks.DataAccess.Utils;
using NHibernate;
using System;
namespace AdventureWorks.DataAccess.Test.repository
{
    [TestFixture]
    public class PersonRepositoryTest : RepositoryTestBase<PersonRepository>
    {

        [Test]
        public void GetPeopleShouldReturnAllPeople()
        {
                var people = repository.GetPersonByFullName(session, "Larry", "Zhang");
                Assert.AreEqual(1, people.Count<Person>());
        }

        [Test]
        public void SearchPeopleWillSetTheirSubClass()
        {
            var customerLinq = repository.GetPersonByFullName(session, "Sarah", "Price");
            Assert.AreEqual(1, customerLinq.Count<Person>());
            var customers = customerLinq.ToList();
            Assert.IsInstanceOf<Customer>(customers[0]);
            var employeeLinq = repository.GetPersonByFullName(session, "Rob", "Walters");
            Assert.AreEqual(1, employeeLinq.Count<Person>());
            var employees = employeeLinq.ToList();
            Assert.IsInstanceOf<Employee>(employees[0]);
        }

        [Test]
        public void GetCustomerByNameWillBringAllProperties()
        {
                var customer = repository.GetPersonByFullName(session, "Sarah", "Price");
                var customerList = customer.ToList();
                Assert.AreEqual(1, customerList.Count);
                Assert.IsInstanceOf<Customer>(customerList[0]);
                Assert.AreEqual("AW00011186", ((Customer) customerList[0]).AccountNumber);
        }

        [Test]
        public void GetEmployeeByNameWillBringAllProperties()
        {
            var employee = repository.GetPersonByFullName(session, "Rob", "Walters");
            var employeeList = employee.ToList();
            Assert.AreEqual(1, employeeList.Count);
            Assert.IsInstanceOf<Employee>(employeeList[0]);
            DateTime d = new DateTime(1969, 1, 23);
            Assert.AreEqual(d, ((Employee) employeeList[0]).BirthDate);
        }


        [Test]
        public void GetPersonWithPhoneNumberShouldReturnCorrectPhoneNumber()
        {
            var person = repository.GetById(session, 6);
            Assert.IsNotNull(person);
            Assert.AreEqual(1, person.Phones.Count);
            Assert.AreEqual("122-555-0189", person.Phones[0].PhoneNumber);
            Assert.AreEqual(PhoneContactType.Work, person.Phones[0].PhoneType);
        }
        
        [Test]
        public void GetPersonWithEmailShouldReturnCorrectValue()
        {
            var person = repository.GetById(session, 6);
            Assert.IsNotNull(person);
            Assert.AreEqual(1, person.Emails.Count);
            Assert.AreEqual("jossef0@adventure-works.com", person.Emails[0]);
        }

        [Test]
        public void UpdateEmailShouldChangeEmail()
        {
            var person = repository.GetById(session, 6);
            Assert.IsNotNull(person);
            Assert.AreEqual(1, person.Emails.Count);
            Assert.AreEqual("jossef0@adventure-works.com", person.Emails[0]);
            person.Emails[0] = "my@d.com";
            repository.Save(session, person);
            session.Flush();
            person = null;
            var p2 = repository.GetById(session, 6);
            Assert.IsNotNull(p2);
            Assert.AreEqual(1, p2.Emails.Count);
            Assert.AreEqual("my@d.com", p2.Emails[0]);
        }

        [Test]
        public void AddEmailShouldAppendToEmailList()
        {
            var person = repository.GetById(session, 6);
            Assert.IsNotNull(person);
            Assert.AreEqual(1, person.Emails.Count);
            Assert.AreEqual("jossef0@adventure-works.com", person.Emails[0]);
            person.Emails.Add("my@d.com");
            repository.Save(session, person);
            person = null;
            var p2 = repository.GetById(session, 6);
            Assert.IsNotNull(p2);
            Assert.AreEqual(2, p2.Emails.Count);
        }


        [Test]
        public void GetByIdShouldReturnAllProperties()
        {
            var person = repository.GetById(session, 1039);
            Assert.AreEqual("James", person.FirstName);
            Assert.AreEqual("Haugh", person.LastName);
            Assert.AreEqual("Mr.", person.Title);
            Assert.AreEqual("B.", person.MiddleName);
            Assert.AreEqual("Jr.", person.Suffix);
        }

        [Test]
        public void UpdatePhoneNumberShouldUpdateProperly()
        {
            var person = repository.GetById(session, 1039);
            Assert.AreEqual(1, person.Phones.Count);
            person.Phones.Add(new PhoneContact { PhoneNumber = "5555555", PhoneType = PhoneContactType.Home });
            repository.Save(session, person);
            person = null;

            var p2 = repository.GetById(session, 1039);
            Assert.AreEqual(2, p2.Phones.Count);

        }
    }
}
